package com.base;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * 所有数据库实体对应的vo对象抽象类
 * 该虚类提供了两个获取xml的接口，方便vo对象的http传输
 * @author 
 */
public abstract class BaseEntity {
    
	/**
	 * 获取当前vo类的完整xml形式（包括当前vo所拥有的子对象数据）
	 * @return
	 */
	public abstract Element xml();
	
	/**
	 * 获取当前vo类的xml形式（不包括当前vo所拥有的子对象数据）
	 * @return
	 */
	public Element currentXml(){
		Field[]  fields = this.getClass().getDeclaredFields();
		String className = this.getClass().getName();
		String name = className.substring(className.lastIndexOf(".") + 1);
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement(name);
		Field.setAccessible(fields,true);
		String field ;
		for(int i = 0 ; i < fields.length ;i++){
			try {
				field = fields[i].getName();
				if(fields[i].getType().toString().equals("interface java.util.List")){
					
				}else{
					String value = String.valueOf(fields[i].get(this));
					this.addAttribute(root, field, value);
				}
				
			} catch (IllegalArgumentException e) {
				System.out.println(e);
			} catch (IllegalAccessException e) {
				System.out.println(e);
			}
		}
		return root;
	}
	
	/**
	 * 获取获取当前vo类的map形式（不包括当前vo所拥有的子对象数据）
	 * @return
	 */
	public Map<String,Object> map(){
		Map<String,Object> map = new HashMap<String, Object>();
		Field[]  fields = this.getClass().getDeclaredFields();
		Field.setAccessible(fields,true);
		String field ;
		for(int i = 0 ; i < fields.length ;i++){
			try {
				field = fields[i].getName();
				if(fields[i].getType().toString().equals("interface java.util.List")){
					
				}else{
					map.put(field, fields[i].get(this));
				}
			} catch (IllegalArgumentException e) {
				System.out.println(e);
			} catch (IllegalAccessException e) {
				System.out.println(e);
			}
		}
		return map;
	}
	
	
	/**
	 * 获取当前vo类的唯一标示
	 * @return
	 */
	public abstract Object getID();
	
	/**
	 * 向Element中添加值操作，防止因值为空引起的异常
	 * @param e <code>org.dom4j.Element<code>
	 * @param text 添加值 可以是 String 及简单类型
	 */
	protected void addText(Element e,Object text){
		if(text == null){
			text = "";
		}
		e.addText(String.valueOf(text));
	}
	
	/**
	 * 向Element中添加属性操作，防止因值为空引起的异常
	 * @param e <code>org.dom4j.Element<code>
	 * @param text 添加值 可以是 String 及简单类型
	 */
	protected void addAttribute(Element e,String name,String text){
		if(text == null){
			text = "";
		}
		e.addAttribute(name, text);
	}
	
	/**
	 *  构建子表vo的xml形式
	 * @param iterable   子表vo集合对象 <code>Iterable</code>
	 * @param name       xml的根节点名
	 * @return  <code>org.dom4j.Element</code> 
	 */
	@SuppressWarnings("unchecked")
	protected Element getChildXml(Iterable iterable,String name){
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement(name);
		if(iterable != null){
			Iterator ite =  iterable.iterator();
			while(ite.hasNext()){
				BaseEntity vo = (BaseEntity)ite.next();
				root.add(vo.xml());
			}
		}
		return root;
	}
	
	/**
	 * 获取指定字段名数组的Xml形式
	 * @param paramters  所需的字段名数组
	 * @param root   生成的xml根标签名
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public Element getValuesXml(String[] paramters,String root) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		Document doc = DocumentHelper.createDocument();
		Element rootXml = doc.addElement(root);
		for(int i = 0 ; i< paramters.length;i++){
			String methodName = "get";
			String paramter = paramters[i];
			String start = paramter.substring(0,1);
			String end = paramter.substring(1);
			methodName = methodName + start.toUpperCase() + end;
			Method method=this.getClass().getMethod(methodName,new Class[0]);
			method.invoke(this, null);
			String value = String.valueOf(method.invoke(this,new Object[0]));
			this.addAttribute(rootXml, paramter, value);
		}
		return rootXml;
	}
	
	
}
